package com.xtaller.sdboot.config.aop;

import com.alibaba.fastjson.JSONObject;
import com.xtaller.sdboot.core.wrapper.RequestWrapper;
import com.xtaller.sdboot.utils.annotation.Log;
import com.xtaller.sdboot.utils.helper.JsonHelper;
import lombok.var;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 * @author : Taller
 * @date : 2020/3/7 14:51
 * @Description :
 */
@Aspect
@Component
public class HttpLog {
    ThreadLocal<Long> startTime = new ThreadLocal<>();
    ThreadLocal<JSONObject> logData = new ThreadLocal<>();
    private final Integer SUCCESS = 200;

    @Pointcut(value = "@annotation(log)", argNames = "log")
    public void pointcut(Log log) {
    }

    @Before("@annotation(com.xtaller.sdboot.utils.annotation.Log)")
    public void before(JoinPoint joinPoint) throws IOException {
        var start = System.currentTimeMillis();
        startTime.set(start);

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Log log = method.getAnnotation(Log.class);
        System.out.println("注解式拦截 " + log.value());
        System.out.println("处理开始时间: " + start);

        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        var token = request.getHeader("token");
        var httpMethod = request.getMethod();
        var path = request.getServletPath();
        var params = request.getParameterMap();
        var body = new RequestWrapper(request).getBodyString();
        var obj = JsonHelper.create().put("token", token)
                .put("method", httpMethod)
                .put("params", JsonHelper.o2s(params))
                .put("body", body)
                .put("url", path)
                .put("ip", request.getRemoteAddr());
        logData.set(obj);
    }

    @AfterReturning(returning = "ret", pointcut = "@annotation(com.xtaller.sdboot.utils.annotation.Log)")
    public void doAfterReturning(Object ret) {
        var end = System.currentTimeMillis() - startTime.get();
        System.out.println("处理结束时间: " + end);

        // 数据采集
        var obj = logData.get();

        obj.put("time", end);
        System.err.println("===aop log===");
        System.err.println(JsonHelper.o2s(obj));

    }
}
